// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#include "Object.h"

#include "vector.h"
#include "physics.h"
#include <vector>
#include "hydroapp.h"

#define TWOPI 2.0*PI

Object::Object(Body* _startBody, Ogre::SceneNode* sn)
{
	//rootBody = _rootBody;
	startBody = _startBody;
	node = sn;
	//physObject = new PhysObject();
	position = Vec3(100000000000,0,0);
	velocity = Vec3(0,0,20000);
	rposition = Ogre::Vector3(0,0,0);
	active = false;
	firedirection = 0;
	power = 6433.;
	pointer = startBody->node->createChildSceneNode();
	pointer->setInheritOrientation(false);
	pointer->resetOrientation();
	msh = app->mSceneMgr->createManualObject("Pointer");
	msh->estimateVertexCount(8);
	msh->begin("Pointer", Ogre::RenderOperation::OT_LINE_LIST);
	msh->position(0, -500, 0);
	msh->position(0, -700, 0);
	msh->position(500, 0, 0);
	msh->position(700, 0, 0);
	msh->position(-500, 0, 0);
	msh->position(-700, 0, 0);
	msh->position(0, 500, 0);
	msh->position(0, 1500, 0);
	msh->end();
	pointer->attachObject(msh);
	rt = app->mSceneMgr->createRibbonTrail("asteroidtrail");
	app->staticNode->attachObject(rt);
	rt->setTrailLength(50000);
	rt->setMaxChainElements(500);
	rt->setNumberOfChains(1);
	rt->addNode(sn);
	ind = rt->getChainIndexForNode(sn);
	rt->setInitialWidth(ind, 80);
	rt->setMaterialName("rt");
	//rt->setColourChange(ind, Ogre::ColourValue(.1, 0, 0, 0));
	trailCleared = 0;
}

Object::~Object(void)
{
	delete msh;
	delete rt;
	delete pointer;
	delete node;
}

void Object::update(void)
{
	if (active) {
		for( iter = app->rootBody->children->begin(); iter != app->rootBody->children->end(); iter++ ) {
			if ((*iter)->mass != 0.0) {
				velocity += rk6_gravity_acceleration(app->clock->dt, position, (*iter)->gposition, (*iter)->mass);
			}
		}
		if (trailCleared > 0) {
			//rt->removeChainElement(ind);
			trailCleared--;
			//trailCleared = false;
		}
		position += velocity * app->clock->dt;
		rposition.x = position.x / 50000000.;
		rposition.y = position.y / 50000000.;
		rposition.z = position.z / 50000000.;
		node->setPosition(rposition);
	}
	pointer->setOrientation(Ogre::Quaternion(Ogre::Radian(firedirection), Ogre::Vector3::UNIT_Z));
	if (firedirection > TWOPI)
		firedirection -= TWOPI;
	if (firedirection < 0)
		firedirection += TWOPI;
}

void Object::launch()
{
	active = true;
	float x = cos(firedirection) * 0.0 - sin(-firedirection) * -1.0;
	float y = sin(firedirection) * 0.0 - cos(-firedirection) * -1.0;
	position = startBody->gposition + (Vec3(x, y, 0) * 10000000000.0);
	velocity = startBody->velocity + (Vec3(x, y, 0) * power);
	rt->removeNode(node);
	rposition.x = position.x / 50000000.;
	rposition.y = position.y / 50000000.;
	rposition.z = position.z / 50000000.;
	node->setPosition(rposition);
	rt->addNode(node);
	//trailCleared = 5;
}